<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>签到语音播报系统</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Microsoft YaHei', Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
        
        .container {
            background: white;
            border-radius: 20px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
            padding: 40px;
            max-width: 600px;
            width: 100%;
        }
        
        h1 {
            text-align: center;
            color: #333;
            margin-bottom: 30px;
            font-size: 28px;
        }
        
        .status {
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 20px;
            border-radius: 10px;
            margin-bottom: 30px;
            font-size: 18px;
            font-weight: bold;
        }
        
        .status.connected {
            background: #d4edda;
            color: #155724;
        }
        
        .status.disconnected {
            background: #f8d7da;
            color: #721c24;
        }
        
        .status.connecting {
            background: #fff3cd;
            color: #856404;
        }
        
        .status-dot {
            width: 12px;
            height: 12px;
            border-radius: 50%;
            margin-right: 10px;
            animation: pulse 2s infinite;
        }
        
        .status.connected .status-dot {
            background: #28a745;
        }
        
        .status.disconnected .status-dot {
            background: #dc3545;
        }
        
        .status.connecting .status-dot {
            background: #ffc107;
        }
        
        @keyframes pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.5; }
        }
        
        .log-container {
            background: #f8f9fa;
            border-radius: 10px;
            padding: 20px;
            max-height: 400px;
            overflow-y: auto;
        }
        
        .log-title {
            font-size: 16px;
            font-weight: bold;
            color: #666;
            margin-bottom: 15px;
        }
        
        .log-item {
            background: white;
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 10px;
            border-left: 4px solid #667eea;
            animation: slideIn 0.3s ease-out;
        }
        
        @keyframes slideIn {
            from {
                opacity: 0;
                transform: translateX(-20px);
            }
            to {
                opacity: 1;
                transform: translateX(0);
            }
        }
        
        .log-item.success {
            border-left-color: #28a745;
        }
        
        .log-item.end {
            border-left-color: #17a2b8;
        }
        
        .log-item.duplicate {
            border-left-color: #ffc107;
        }
        
        .log-time {
            font-size: 12px;
            color: #999;
            margin-bottom: 5px;
        }
        
        .log-message {
            font-size: 16px;
            color: #333;
            font-weight: bold;
            margin-bottom: 8px;
        }
        
        .log-details {
            font-size: 14px;
            color: #666;
        }
        
        .controls {
            margin-top: 20px;
            display: flex;
            gap: 10px;
        }
        
        button {
            flex: 1;
            padding: 12px 24px;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s;
        }
        
        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(0,0,0,0.2);
        }
        
        .btn-clear {
            background: #6c757d;
            color: white;
        }
        
        .btn-test {
            background: #667eea;
            color: white;
        }
        
        .volume-control {
            margin-top: 20px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
        }
        
        .volume-label {
            font-size: 14px;
            color: #666;
            margin-bottom: 8px;
        }
        
        input[type="range"] {
            width: 100%;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🔊 签到语音播报系统</h1>
        
        <div id="status" class="status connecting">
            <span class="status-dot"></span>
            <span id="statusText">正在连接...</span>
        </div>
        
        <div class="volume-control">
            <div class="volume-label">音量控制: <span id="volumeValue">80</span>%</div>
            <input type="range" id="volumeSlider" min="0" max="100" value="80">
        </div>
        
        <div class="controls">
            <button class="btn-test" onclick="testVoice()">🔊 测试语音</button>
            <button class="btn-clear" onclick="clearLogs()">🗑️ 清空日志</button>
        </div>
        
        <div class="log-container">
            <div class="log-title">📋 签到记录</div>
            <div id="logs"></div>
        </div>
    </div>

    <script>
        let ws = null;
        let reconnectTimer = null;
        let currentVolume = 0.8;

        // 检查浏览器是否支持 Web Speech API
        const SpeechSynthesisUtterance = window.SpeechSynthesisUtterance || window.webkitSpeechSynthesisUtterance;
        const speechSynthesis = window.speechSynthesis || window.webkitSpeechSynthesis;
        
        // 连接WebSocket
        function connectWebSocket() {
            const wsUrl = 'ws://8.217.73.7:8779';
            updateStatus('connecting', '正在连接...');
            
            ws = new WebSocket(wsUrl);
            
            ws.onopen = function() {
                console.log('WebSocket连接成功');
                updateStatus('connected', '已连接');
                addLog('系统', '连接成功', '');
                
                // 清除重连定时器
                if (reconnectTimer) {
                    clearTimeout(reconnectTimer);
                    reconnectTimer = null;
                }
            };
            
            ws.onmessage = function(event) {
                console.log('收到消息:', event.data);
                
                try {
                    const message = JSON.parse(event.data);
                    handleMessage(message);
                } catch (e) {
                    console.error('解析消息失败:', e);
                }
            };
            
            ws.onerror = function(error) {
                console.error('WebSocket错误:', error);
                updateStatus('disconnected', '连接错误');
            };
            
            ws.onclose = function() {
                console.log('WebSocket连接关闭');
                updateStatus('disconnected', '连接断开');
                
                // 5秒后自动重连
                reconnectTimer = setTimeout(function() {
                    console.log('尝试重新连接...');
                    connectWebSocket();
                }, 5000);
            };
        }
        
        // 处理消息
        function handleMessage(message) {
            console.log('处理消息:', message);
            
            if (message.type === 'welcome') {
                console.log('欢迎消息:', message.message);
                return;
            }
            
            if (message.type === 'voice_play') {
                playVoice(message);
            }
        }
        
        // 播放语音（使用 Web Speech API）
        function playVoice(message) {
            const voiceType = message.voice_type;
            const voiceMessage = message.voice_message;
            const data = message.data || {};

            console.log('播放语音:', voiceType, voiceMessage, data);

            // 使用 Web Speech API 播放文字
            if (SpeechSynthesisUtterance && speechSynthesis) {
                try {
                    // 停止之前的语音
                    speechSynthesis.cancel();

                    // 创建语音对象
                    const utterance = new SpeechSynthesisUtterance(voiceMessage);
                    utterance.lang = 'zh-CN';  // 中文
                    utterance.rate = 1.0;      // 语速：0.1-10，默认1
                    utterance.pitch = 1.0;     // 音调：0-2，默认1
                    utterance.volume = currentVolume;  // 音量：0-1

                    // 播放
                    speechSynthesis.speak(utterance);

                    console.log('Web Speech API 播放成功');
                } catch (e) {
                    console.error('Web Speech API 播放失败:', e);
                    addLog('错误', '语音播放失败', e.message);
                }
            } else {
                console.warn('浏览器不支持 Web Speech API');
                addLog('警告', '浏览器不支持语音播放', '请使用现代浏览器（Chrome、Edge、Safari等）');
            }

            // 显示日志
            let logMessage = '';
            let logDetails = '';

            if (voiceType === 'success') {
                logMessage = '✅ 签到开始';
                logDetails = `会员：${data.member_name || '未知'} | 卡号：${data.card_no || '未知'}`;
            } else if (voiceType === 'end') {
                logMessage = '🏁 签到结束';
                logDetails = `会员：${data.member_name || '未知'} | 时长：${data.duration_minutes || 0}分钟 | 积分：+${data.points || 0}`;
            } else if (voiceType === 'duplicate') {
                logMessage = '⚠️ 重复刷脸';
                logDetails = `会员：${data.member_name || '未知'} | 间隔：${data.interval || 0}秒`;
            }

            addLog(voiceType, logMessage, logDetails);
        }
        
        // 更新状态
        function updateStatus(status, text) {
            const statusEl = document.getElementById('status');
            const statusTextEl = document.getElementById('statusText');
            
            statusEl.className = 'status ' + status;
            statusTextEl.textContent = text;
        }
        
        // 添加日志
        function addLog(type, message, details) {
            const logsEl = document.getElementById('logs');
            const time = new Date().toLocaleTimeString('zh-CN');
            
            const logItem = document.createElement('div');
            logItem.className = 'log-item ' + type;
            logItem.innerHTML = `
                <div class="log-time">${time}</div>
                <div class="log-message">${message}</div>
                <div class="log-details">${details}</div>
            `;
            
            logsEl.insertBefore(logItem, logsEl.firstChild);
            
            // 最多保留50条日志
            while (logsEl.children.length > 50) {
                logsEl.removeChild(logsEl.lastChild);
            }
        }
        
        // 清空日志
        function clearLogs() {
            document.getElementById('logs').innerHTML = '';
        }
        
        // 测试语音
        function testVoice() {
            if (SpeechSynthesisUtterance && speechSynthesis) {
                try {
                    speechSynthesis.cancel();
                    const utterance = new SpeechSynthesisUtterance('测试语音，签到成功');
                    utterance.lang = 'zh-CN';
                    utterance.rate = 1.0;
                    utterance.pitch = 1.0;
                    utterance.volume = currentVolume;
                    speechSynthesis.speak(utterance);
                    addLog('test', '🔊 测试语音', '播放测试提示音');
                } catch (e) {
                    alert('播放失败：' + e.message);
                }
            } else {
                alert('浏览器不支持 Web Speech API');
            }
        }
        
        // 音量控制
        document.getElementById('volumeSlider').addEventListener('input', function(e) {
            currentVolume = e.target.value / 100;
            document.getElementById('volumeValue').textContent = e.target.value;
        });
        
        // 页面加载时连接
        window.onload = function() {
            connectWebSocket();
        };
    </script>
</body>
</html>

